<?php

namespace app\admin\dao;

use app\admin\traits\MemberFromTrait;
use app\common\model\AccountBill;
use app\common\model\Member;
use app\common\model\MemberDraft;
use app\common\model\Trade;
use ShidianUtil\Thinkphp\Dao\DaoTrait;
use think\Collection;
use think\facade\Config;

/**
 * MemberDao 数据访问对象
 * Class MemberDao
 * @package app\dao
 * @method Member findByPK(?int $id, $field = true)
 * @method \think\Collection selectAll(?int $page, ?int $page_size, $field = true)
 * @method Member insertActive(array $params, array $allow_field = [])
 * @method Member updateActive(Member $model, array $params, array $allow_field = [])
 * @method Member findAndUpdateActive(int $id, array $params, array $allow_field = [])
 * @method Member updateActiveByClosure(\Closure $closure, array $params, array $allow_field = [])
 * @method void deleteModel(Member $model)
 * @method void deleteById(int|array|\Closure $id, bool $force = false)
 * @link https://www.kancloud.cn/manual/thinkphp6_0/1037579
 * @link https://www.kancloud.cn/manual/think-orm/1257998
 * @link https://www.kancloud.cn/thinkphp/master-database-and-model/265551
 */
class MemberDao
{
    use DaoTrait;
    use MemberFromTrait;

    /**
     * @var \app\common\model\Member
     */
    private $baseModel;

    /**
     * MemberDao constructor.
     */
    public function __construct()
    {
        $this->baseModel = Member::class;
    }

    public function findLawyer($id): ?Member
    {
        $record = Member::where('id', $id)
                        ->with([
                            'fromChain',
                        ])
                        ->append(['headImg', 'headImgThumb', 'cropImg', 'showName'])
                        ->find();

        $this->wrapMemberChannelStr($record);

        return $record;
    }

    public function selectSvip(?int $page, ?int $page_size)
    {

        $tableName = Member::getTable();

        $collection = Member::where('svip', 1)
                            ->tableField(['id', 'type', 'nickname', 'realname', 'phone', 'headImgUrl', 'channel', 'followedWechat', 'created'], $tableName)
                            ->with([
                                'fromChain',
                            ])
                            ->append(['headImg', 'headImgThumb', 'cropImg', 'showName'])
                            ->order("$tableName.id", 'desc')
                            ->paging($page, $page_size)
                            ->select();

        $this->wrapMemberCollectionChannelStr($collection);

        return $collection;
    }

    /**
     * 入驻律师导出列表
     * @param $startTime
     * @param $endTime
     * @return Collection
     */
    public function selectForExport($startTime, $endTime): Collection
    {
        $tableName = Member::getTable();

        $cardTotalSumSql = AccountBill::where(function ($query) use ($tableName) {
            $query->whereOr(function ($query) use ($tableName) {
                $query->whereRaw("fromMemberId=$tableName.id")
                      ->where('fromType', 'member');
            })->whereOr(function ($query) use ($tableName) {
                $query->whereRaw("proxyMemberId=$tableName.id")
                      ->where('fromType', 'company');
            });
        })
                                      ->where('accountType', 'card')
                                      ->fieldRaw('sum(`money`)')
                                      ->buildSql();

        $coinTotalSumSql = AccountBill::where(function ($query) use ($tableName) {
            $query->whereOr(function ($query) use ($tableName) {
                $query->whereRaw("fromMemberId=$tableName.id")
                      ->where('fromType', 'member');
            })->whereOr(function ($query) use ($tableName) {
                $query->whereRaw("proxyMemberId=$tableName.id")
                      ->where('fromType', 'company');
            });
        })
                                      ->where('accountType', 'coin')
                                      ->fieldRaw('sum(`money`)')
                                      ->buildSql();


        $collection = Member::where('type', 1)
                            ->timeRange($startTime, $endTime, 'created', 'created')
                            ->field(true)
                            ->field([
                                $cardTotalSumSql => 'cardTotalSum',
                                $coinTotalSumSql => 'coinTotalSum',
                            ])
                            ->with([
                                'city',
                                'memberInfo',
                                'account',
                                'card',
                                'coin',
                                'fromChain',
                            ])
                            ->withSum([
                                'tokenRechargeTrades' => fn($query) => $query->where('payStatus', Trade::PAID),
                            ], 'payMoney')
                            ->withAttr([
                                'cardTotalSum' => fn($value) => $value ?: 0,
                                'coinTotalSum' => fn($value) => $value ?: 0,
                                'token_recharge_trades_sum' => fn($value) => $value ?: 0,
                            ])
                            ->select();

        $this->wrapMemberCollectionChannelStr($collection);

        return $collection;
    }

    public function selectForBalanceExport($card_balance): Collection
    {
        $tableName = Member::getTable();

        $payment_account = PAYMENT_ACCOUNT;
        $payment_card = PAYMENT_CARD;
        $payment_coin = PAYMENT_COIN;

        return Member::leftJoin('account a', "$tableName.id=a.memberId and a.payMethod='$payment_account'")
                     ->leftJoin('account card', "$tableName.id=card.memberId and card.payMethod='$payment_card'")
                     ->leftJoin('account coin', "$tableName.id=coin.memberId and coin.payMethod='$payment_coin'")
                     ->where('type', 1)
                     ->whereIn('status', [0, 1])
                     ->when(is_numeric($card_balance), fn($query) => $query->where('card.balance', '>=', $card_balance))
                     ->tableField(true, $tableName)
                     ->tableField([
                         'a.balance' => 'accountBalance',
                     ], 'a')
                     ->tableField([
                         'card.balance' => 'cardBalance',
                     ], 'card')
                     ->tableField([
                         'coin.balance' => 'coinBalance',
                     ], 'coin')
                     ->with([
                         'city',
                     ])
                     ->withAttr([
                         'accountBalance' => fn($value) => $value ?? 0,
                         'cardBalance' => fn($value) => $value ?? 0,
                         'coinBalance' => fn($value) => $value ?? 0,
                     ])
                     ->select();
    }


    /**
     * 被邀请人-列表
     * @param $channel
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param int|null $page
     * @param int|null $page_size
     * @return array
     */
    public function listMembersInvited($channel, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId, ?int $page, ?int $page_size): array
    {

        $tableName = Member::getTable();

        $query = $this->getMemberInvitedQuery($channel, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId)
            // ->force('memberIdInvite')
                      ->tableField(['id', 'type', 'nickname', 'realname', 'phone', 'headImgUrl', 'channel', 'followedWechat', 'created'], $tableName)
                      ->with([
                          'inviteMember' => fn(\think\db\Query $query) => $query->tableField(['id', 'type', 'nickname', 'realname', 'headImgUrl', 'cropImgUrl'], $tableName)->append(['headImg', 'headImgThumb', 'cropImg', 'showName']),
                          'fromChain',
                      ])
                      ->withSum([
                          'trades' => fn($query) => $query->where('payStatus', Trade::PAID)
                                                          ->where('refundStatus', '<>', Trade::REFUNDED)
                                                          ->where('settleStatus', 'SETTLED')
                                                          ->when(is_id($inviteId), fn($query) => $query->where('settleInviterId', $inviteId), fn($query) => $query->where('settleInviterId', '<>', '0'))
                                                          ->where('tradeType', TRADE_TOKEN_RECHARGE),
                      ], 'payMoney', false)
                      ->withSum([
                          'settledTrades' => fn($query) => $query->where('payStatus', Trade::PAID)
                                                                 ->where('refundStatus', '<>', Trade::REFUNDED)
                                                                 ->where('settleStatus', 'SETTLED')
                                                                 ->when(is_id($inviteId), fn($query) => $query->where('settleInviterId', $inviteId), fn($query) => $query->where('settleInviterId', '<>', '0'))
                                                                 ->where('tradeType', TRADE_TOKEN_RECHARGE),
                      ], 'settleInviterMoney', false)
                      ->withAttr([
                          'trades_sum' => fn($value) => $value ?: '0',
                          'settled_trades_sum' => fn($value) => $value ?: '0',
                      ])
                      ->append(['headImg', 'headImgThumb', 'cropImg', 'showName'])
                      ->order("mi.id", 'desc')
                      ->order("$tableName.id", 'desc')
                      ->paging($page, $page_size);

        $data = listOutput($query, $page_size);

        $this->wrapMemberCollectionChannelStr($data['list']);

        return $data;
    }

    /**
     * 被邀请人-列表统计
     * @param $channel
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @return array
     */
    public function statisticsListMembersInvited($channel, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId): array
    {
        $count_query = $this->getMemberInvitedQuery($channel, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId);

        $tableName = Trade::getTable();
        $trades_sum = Trade::leftJoin('member m', "$tableName.memberId=m.id")
                           ->where('payStatus', Trade::PAID)
                           ->where('refundStatus', '<>', Trade::REFUNDED)
                           ->where('settleStatus', 'SETTLED')
                           ->when(is_id($inviteId), fn($query) => $query->where('settleInviterId', $inviteId), fn($query) => $query->where('settleInviterId', '<>', '0'))
                           ->where('tradeType', TRADE_TOKEN_RECHARGE)
                           ->when(is_numeric($channel), fn($query) => $query->where('m.channel', $channel))
                           ->when(is_id($provinceId), fn($query) => $query->where('m.provinceId', $provinceId))
                           ->when(is_id($cityId), fn($query) => $query->where('m.cityId', $cityId))
                           ->when(is_numeric($startTime), fn($query) => $query->where('m.created', '>=', $startTime))
                           ->when(is_numeric($endTime), fn($query) => $query->where('m.created', '<=', $endTime))
                           ->whereIn("m.status", [0, 1])
                           ->search('m.nickname|m.phone', $kw)
                           ->sum('payMoney');

        $settled_trades_sum = Trade::leftJoin('member m', "$tableName.memberId=m.id")
                                   ->where('payStatus', Trade::PAID)
                                   ->where('refundStatus', '<>', Trade::REFUNDED)
                                   ->where('settleStatus', 'SETTLED')
                                   ->when(is_id($inviteId), fn($query) => $query->where('settleInviterId', $inviteId), fn($query) => $query->where('settleInviterId', '<>', '0'))
                                   ->where('tradeType', TRADE_TOKEN_RECHARGE)
                                   ->when(is_numeric($channel), fn($query) => $query->where('m.channel', $channel))
                                   ->when(is_id($provinceId), fn($query) => $query->where('m.provinceId', $provinceId))
                                   ->when(is_id($cityId), fn($query) => $query->where('m.cityId', $cityId))
                                   ->when(is_numeric($startTime), fn($query) => $query->where('m.created', '>=', $startTime))
                                   ->when(is_numeric($endTime), fn($query) => $query->where('m.created', '<=', $endTime))
                                   ->whereIn("m.status", [0, 1])
                                   ->search('m.nickname|m.phone', $kw)
                                   ->sum('settleInviterMoney');

        return [
            'total_count' => $count_query->count(),
            'trades_sum' => $trades_sum,
            'settled_trades_sum' => $settled_trades_sum,
        ];
    }

    /**
     *
     * @param $channel
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param $inviteId
     * @return Member
     */
    private function getMemberInvitedQuery($channel, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId)
    {
        $tableName = Member::getTable();
        return Member::rightJoin('member_invite mi', "$tableName.id=mi.memberIdInvite and mi.status = 1")
                     ->when(is_id($inviteId),
                         fn($query) => $query->where('mi.memberId', $inviteId)
                     )
                     ->when(is_numeric($channel), fn($query) => $query->where('channel', $channel))
                     ->when(is_id($provinceId), fn($query) => $query->where('provinceId', $provinceId))
                     ->when(is_id($cityId), fn($query) => $query->where('cityId', $cityId))
                     ->when(is_numeric($startTime), fn($query) => $query->where("$tableName.created", '>=', $startTime))
                     ->when(is_numeric($endTime), fn($query) => $query->where("$tableName.created", '<=', $endTime))
                     ->whereIn("$tableName.status", [0, 1])
                     ->search('nickname|realname|phone', $kw);
    }

    /**
     * 普通用户-列表查询
     * @param $channel
     * @param $chain
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param $inviteId
     * @param int|null $page
     * @param int|null $page_size
     * @return array
     */
    public function listMembers($channel, $chain, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId, ?int $page, ?int $page_size): array
    {
        $tableName = Member::getTable();

        $query = Member::when(is_id($inviteId), fn($query) => $query->leftJoin('member_invite mi', "$tableName.id=mi.memberIdInvite and mi.status = 1")->where('mi.memberId', $inviteId))
                       ->where('type', '0')
                       ->when(is_numeric($channel), fn($query) => $query->where('channel', $channel))
                       ->when(is_id($provinceId), fn($query) => $query->where('provinceId', $provinceId))
                       ->when(is_id($cityId), fn($query) => $query->where('cityId', $cityId))
                       ->when(is_numeric($startTime), fn($query) => $query->where('created', '>=', $startTime))
                       ->when(is_numeric($endTime), fn($query) => $query->where('created', '<=', $endTime))
                       ->when(not_blank($chain), fn($query) => $query->where('chain', $chain))
                       ->whereIn("$tableName.status", [0, 1])
                       ->search("$tableName.id|nickname|phone", $kw)
                       ->tableField(true, $tableName)
                       ->with([
                           'province' => fn($query) => $query->shortArea(),
                           'city' => fn($query) => $query->shortArea(),
                           'inviteMember' => fn(\think\db\Query $query) => $query->tableField(['id', 'nickname', 'headImgUrl', 'cropImgUrl'], $tableName)->append(['headImg', 'headImgThumb', 'cropImg']),
                           'mutedUser' => fn($query) => $query->field(['id', 'name']),
                           'disabledUser' => fn($query) => $query->field(['id', 'name']),
                           'fromChain',
                       ])
                       ->withCount([
                           'freeAsk' => fn($query) => $query->where('consultingType', '0')->where('status', '>=', '1'),
                           'notFreeAsk' => fn($query) => $query->where('consultingType', '1')->where('status', '>=', '1'),
                       ], false)
                       ->withSum([
                           'trades' => fn($query) => $query->where('payStatus', Trade::PAID),
                       ], 'totalMoney')
                       ->withAttr([
                           'trades_sum' => fn($value) => $value ?: 0,
                       ])
                       ->append(['headImg', 'headImgThumb', 'cropImg', 'showName'])
                       ->shield()
                       ->order("$tableName.id", 'desc')
                       ->paging($page, $page_size);

        $data = listOutput($query, $page_size);

        $this->wrapMembers($data['list']);

        $this->wrapMemberCollectionChannelStr($data['list']);

        return $data;
    }

    /**
     * 普通用户-列表统计
     * @param $channel
     * @param $chain
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param $inviteId
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function statisticsListMembers($channel, $chain, $provinceId, $cityId, $startTime, $endTime, $kw, $inviteId): array
    {
        $tableName = Member::getTable();

        $query = Member::when(is_id($inviteId), fn($query) => $query->leftJoin('member_invite mi', "$tableName.id=mi.memberIdInvite and mi.status = 1")->where('mi.memberId', $inviteId))
                       ->where('type', '0')
                       ->when(is_numeric($channel), fn($query) => $query->where('channel', $channel))
                       ->when(is_id($provinceId), fn($query) => $query->where('provinceId', $provinceId))
                       ->when(is_id($cityId), fn($query) => $query->where('cityId', $cityId))
                       ->when(is_numeric($startTime), fn($query) => $query->where('created', '>=', $startTime))
                       ->when(is_numeric($endTime), fn($query) => $query->where('created', '<=', $endTime))
                       ->when(not_blank($chain), fn($query) => $query->where('chain', $chain))
                       ->whereIn("$tableName.status", [0, 1])
                       ->search('nickname|phone', $kw);

        return [
            'today_count' => $query->count(),
            'wechat_mini_count' => (clone $query)->where('channel', '4')->count(),
            'douyin_mini_count' => (clone $query)->where('channel', '9')->count(),
        ];
    }

    private function wrapMembers(Collection $collection)
    {
        $collection->each(function (Member $member) {
            $mutedCauseStr = '';
            $disabledCauseStr = '';
            if ($member->status == 0) {
                $disabledCauseStr = ($member->disabledUser['name'] ?? '') . '在' . date('Y-m-d H:i:s', $member->disabledActionTime) . '封号';
            }
            if ($member->muted == 1) {
                if ($member->mutedLength == 5) {
                    $mutedCauseStr = ($member->mutedUser['name'] ?? '') . '在' . date('Y-m-d H:i:s', $member->mutedActionTime) . '永久禁言，原因是：' . $member->mutedCause;
                } else {
                    $mutedCauseStr = ($member->mutedUser['name'] ?? '') . '在' . date('Y-m-d H:i:s', $member->mutedActionTime) . '禁言至' . date('Y-m-d H:i:s', $member->mutedTime) . '，原因是：' . $member->mutedCause;
                }
            }

            $member->mutedCauseStr = $mutedCauseStr;
            $member->disabledCauseStr = $disabledCauseStr;
        });
    }

    /**
     * 律师-列表查询
     * @param $followedWechat
     * @param $medal
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param $svip
     * @param $svipAgree
     * @param $subType
     * @param int|null $page
     * @param int|null $page_size
     * @return array
     */
    public function listLawyers($followedWechat, $medal, $provinceId, $cityId, $startTime, $endTime, $kw, $svip, $svipAgree, $subType, ?int $page, ?int $page_size): array
    {
        $tableName = Member::getTable();

        $query = Member::leftJoin('member_info i', "$tableName.id=i.memberId");

        $query = $this->queryLawyers($query, $followedWechat, $medal, $provinceId, $cityId, $startTime, $endTime, $kw, $svip, $svipAgree, $subType);

        $query->tableField(true, $tableName)
              ->with([
                  'memberInfo' => function ($query) {
                      $query->append(['certificatePicImg', 'idcardPicImg', 'idcard2PicImg',])
                            ->hidden(['certificatePic', 'idcardPic', 'idcard2Pic',])
                            ->with([
                                'province' => fn($query) => $query->shortArea(),
                                'city' => fn($query) => $query->shortArea(),
                            ]);
                  },
                  'account',
                  'margin',
                  'mutedUser' => fn($query) => $query->field(['id', 'name']),
                  'disabledUser' => fn($query) => $query->field(['id', 'name']),
                  'inviteMember' => fn(\think\db\Query $query) => $query->tableField(['id', 'nickname', 'realname', 'headImgUrl', 'cropImgUrl', 'type',], $tableName)->append(['headImg', 'headImgThumb', 'cropImg', 'showName']),
                  'svipProvinces',
              ])
              ->withCount([
                  'lawyerFreeAsk' => fn($query) => $query->where('consultingType', '0'),
                  'lawyerNotFreeAsk' => fn($query) => $query->where('consultingType', '1'),
              ], false)
              ->withCount([
                  'lawyerSvipAsk' => fn($query) => $query->where("$tableName.svip", 1)
                                                         ->whereRaw("count_table.rushTime>=$tableName.svipTime"),
              ], true)
              ->append(['headImg', 'headImgThumb', 'cropImg', 'showName', 'todo', 'svipProvincesIds'])
              ->hidden(['svipProvinces'])
              ->shield()
            // ->order('i.practiceTime', 'DESC')
              ->order("$tableName.status", 'DESC')
            // ->order("$tableName.followedWechat", 'DESC')
              ->order('i.checkTime', 'DESC')
              ->order('id', 'DESC')
              ->paging($page, $page_size);

        $data = listOutput($query, $page_size);

        $this->wrapMembers($data['list']);

        return $data;
    }

    /**
     * 律师-列表统计
     * @param $medal
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function statisticsListLawyers($followedWechat, $medal, $provinceId, $cityId, $startTime, $endTime, $kw, $svip, $svipAgree, $subType): array
    {
        $tableName = Member::getTable();

        $query = Member::leftJoin('member_info i', "$tableName.id=i.memberId");

        $query = $this->queryLawyers($query, $followedWechat, $medal, $provinceId, $cityId, $startTime, $endTime, $kw, $svip, $svipAgree, $subType);


        $query2 = MemberDraft::when(is_id($provinceId), fn($query) => $query->where('provinceId', $provinceId))
                             ->when(is_id($cityId), fn($query) => $query->where('cityId', $cityId))
                             ->when(is_numeric($startTime), fn($query) => $query->where("created", '>=', $startTime))
                             ->when(is_numeric($endTime), fn($query) => $query->where("created", '<=', $endTime))
                             ->search("realname|practicingLawFirm", $kw);

        return [
            'total_count' => $query->count(),
            'gold_medal_count' => (clone $query)->where('medal', '1')->count(),
            'svip_count' => (clone $query)->where("$tableName.svip", '1')->count(),
            'check0_count' => $query2->count(),
        ];
    }

    private function queryLawyers($query, $followedWechat, $medal, $provinceId, $cityId, $startTime, $endTime, $kw, $svip, $svipAgree, $subType)
    {
        $testAccount = Config::get('member.testAccount', []);

        $tableName = Member::getTable();

        $query->where("$tableName.type", '1')
              ->where("$tableName.subType", $subType)
              ->when(is_numeric($followedWechat), fn($query) => $query->where("$tableName.followedWechat", $followedWechat))
              ->when(is_id($provinceId), fn($query) => $query->where('i.provinceId', $provinceId))
              ->when(is_id($cityId), fn($query) => $query->where('i.cityId', $cityId))
              ->when(is_numeric($startTime), fn($query) => $query->where("$tableName.settledTime", '>=', $startTime))
              ->when(is_numeric($endTime), fn($query) => $query->where("$tableName.settledTime", '<=', $endTime))
              ->when(is_numeric($svip), fn($query) => $query->where("$tableName.svip", $svip))
              ->when(is_numeric($svipAgree), fn($query) => $query->where("$tableName.svipAgree", $svipAgree))
              ->when(is_numeric($medal), fn($query) => $query->where('i.medal', $medal))
              ->whereIn('status', [0, 1]);

        if (not_blank($kw) && $kw === 'test') {
            if (!empty($testAccount)) {
                $query->whereIn("$tableName.phone", $testAccount);
            }

        } else {
            if (!empty($testAccount)) {
                $query->whereNotIn("$tableName.phone", $testAccount);
            }

            $query->search("$tableName.id|$tableName.realname|phone|practicingLawFirm", $kw);
        }

        return $query;
    }

    /**
     * 推广者-列表查询
     * @param $provinceId
     * @param $cityId
     * @param $startTime
     * @param $endTime
     * @param $kw
     * @param int|null $page
     * @param int|null $page_size
     * @return array
     */
    public function listPromoters($provinceId, $cityId, $startTime, $endTime, $kw, ?int $page, ?int $page_size): array
    {
        $tableName = Member::getTable();

        $query = Member::where("$tableName.isInviter", '1')
                       ->when(is_id($provinceId), fn($query) => $query->where("$tableName.provinceId", $provinceId))
                       ->when(is_id($cityId), fn($query) => $query->where("$tableName.cityId", $cityId))
                       ->when(is_numeric($startTime), fn($query) => $query->where("$tableName.created", '>=', $startTime))
                       ->when(is_numeric($endTime), fn($query) => $query->where("$tableName.created", '<=', $endTime))
                       ->whereIn('status', [0, 1])
                       ->search('nickname|phone', $kw)
                       ->field(true)
                       ->with([
                           'account',
                           'memberInfo',
                           'province' => fn($query) => $query->shortArea(),
                           'city' => fn($query) => $query->shortArea(),
                           'mutedUser' => fn($query) => $query->field(['id', 'name']),
                           'disabledUser' => fn($query) => $query->field(['id', 'name']),
                       ])
                       ->withCount(['inviteMembers'], false)
                       ->append(['headImg', 'headImgThumb', 'cropImg', 'showName', 'todo'])
                       ->shield()
                       ->order('id', 'desc')
                       ->paging($page, $page_size);

        $data = listOutput($query, $page_size);

        $this->wrapMembers($data['list']);

        return $data;
    }

    public function findMember($id)
    {
        return Member::where('id', $id)
                     ->whereIn('status', [0, 1])
                     ->append(['showName'])
                     ->find();
    }
}
